package hnx.ca.security;

import hnx.ca.db.dao.TblAccountCADAO;
import hnx.ca.db.object.AccountCA;
import hnx.ca.entity.DecryptStringResult;
import hnx.ca.entity.EncryptStringResult;
import hnx.ca.entity.SignStringResult;
import hnx.ca.entity.VerifyStringResult;
import hnx.ca.util.Base64Utils;
import hnx.ca.util.ErrorCodes;
import hnx.ca.util.ErrorMessages;
import hnx.ca.util.RootConfig;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration;
import java.util.Properties;

import javax.crypto.Cipher;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Base64;


public class StringVerifier {
	public static Properties props = new Properties();
	public static String certPassword;
	private static String requiredInfo = "30819f300d06092a864886f70d010101050003818d00";
	public static VerifyStringResult verifyString(String orignialText, String signature, String customerId){
		VerifyStringResult verifyStringResult = new VerifyStringResult();
		try {
			AccountCA accountCa = TblAccountCADAO.getAccountCA(customerId);
			
			int checkCustomer = validateCustomer(accountCa);
			if(checkCustomer != ErrorCodes.VERIFY_CUSTOMER.VALID_CUSTOMER){
				verifyStringResult.setErrorCode(checkCustomer);
				verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.INVALID_CUSTOMER);
				return verifyStringResult;
			}
			
			PublicKey publicKey = getPublicKey(requiredInfo + accountCa.getPublicKey());
			byte[] sign = Base64Utils.base64Decode(signature);
			Boolean isValidSign = verifySig(orignialText.getBytes(), publicKey, sign);
			
			if(isValidSign){
				//X509Certificate mCertificate = (X509Certificate) cert;
				X509Certificate mCertificate = null;
					/*
					 * check certificate is valid CRL
					 */
					Boolean isValidCrl = XMLVerifier.verifyCRL(mCertificate);
					if(isValidCrl){
						verifyStringResult.setErrorCode(ErrorCodes.VERIFY_STRING.VALID_SIGNATURE);
						verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.VALID_SIGNATURE);
						verifyStringResult.setSerial(XMLVerifier.getSerialNumber(mCertificate));
					}else{
						verifyStringResult.setErrorCode(ErrorCodes.VERIFY_STRING.CHECK_CRL_FAIL);
						verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.CHECK_CRL_FAIL);
					}
				
			}else{
				verifyStringResult.setErrorCode(ErrorCodes.VERIFY_STRING.INVALID_SIGNATURE);
				verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.INVALID_SIGNATURE);
			}
			
		} catch (CertificateException e){
			verifyStringResult.setErrorCode(ErrorCodes.VERIFY_STRING.CERTIFICATE_EXCEPTION);
			verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.CERTIFICATE_EXCEPTION);
			e.printStackTrace();
		} catch (IOException e) {
			verifyStringResult.setErrorCode(ErrorCodes.VERIFY_STRING.IO_EXCEPTION);
			verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.IO_EXCEPTION);
			e.printStackTrace();
		} catch (Exception e) {
			verifyStringResult.setErrorCode(ErrorCodes.VERIFY_STRING.OTHER_EXCEPTION);
			verifyStringResult.setErrorMessage(ErrorMessages.VERIFY_STRING.OTHER_EXCEPTION);
			e.printStackTrace();
		}
		return verifyStringResult;
	}

	public static DecryptStringResult decryptString(String encodedBase64String){
		DecryptStringResult decryptStringResult = new DecryptStringResult();
		try {
			String originalText = decryptData(encodedBase64String, getPrivateKey());
			decryptStringResult.setErrorCode(0);
			decryptStringResult.setOriginalText(originalText);
		} catch(Exception e){
			e.printStackTrace();
			decryptStringResult.setErrorCode(-2);
		}
		return decryptStringResult;
	}
	
	private static boolean isNacencommCa(String accountCaIssuer) {
		if(StringUtils.isEmpty(accountCaIssuer))
		return false;
		else {
			if (accountCaIssuer.contains("CA2")) return true;
			else return false;
		}
	}


	public static PublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
	    byte[] pubKey = hexStringToByteArray(publicKey);
	    return KeyFactory.getInstance("RSA", "BC").generatePublic(new X509EncodedKeySpec(pubKey));
	}


	public static boolean verifySig(byte[] data, PublicKey key, byte[] sig) throws Exception {
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		Signature signer = Signature.getInstance("SHA1withRSA","BC");
	    signer.initVerify(key);
	    signer.update(data);

	    boolean valido = false;
	    try{
	        valido = signer.verify(sig);
	    }catch(Exception e){
	        e.printStackTrace();
	        valido = false;
	    }
	    return valido;
	  }
	
	public static void main(String args[]) throws Exception{
//		String customerId = "CIMS0003342";
//		String orginalText = "hongson";
//		String encodedBase64String = Base64Utils.base64Encode(orginalText.getBytes());
//		System.out.println(encodedBase64String);
//		EncryptStringResult encryptStringResult = encryptString(encodedBase64String, customerId);
		
		
//		String decryptText = encryptStringResult.getEncryptedResult();
//		String text = decryptData(decryptText, getPrivateKey());
//		System.out.println(text);
//		System.out.println(new String(Base64Utils.base64Decode(text)));
		
		
	}

	public static byte[] hexStringToByteArray(String s) {
	    int len = s.length();
	    byte[] data = new byte[len / 2];
	    for (int i = 0; i < len; i += 2) {
	        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
	                             + Character.digit(s.charAt(i+1), 16));
	    }
	    return data;
	}	

	public static String bytesToHex(byte[] in) {
	    final StringBuilder builder = new StringBuilder();
	    for(byte b : in) {
	        builder.append(String.format("%02x", b));
	    }
	    return builder.toString();
	}
	
	public static void test() throws CertificateException, UnsupportedEncodingException{
		String certString = "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";
		Certificate myCert = CertificateFactory
			     .getInstance("X509")
			     .generateCertificate(
                                   // string encoded with default charset
				new ByteArrayInputStream(certString.getBytes("UTF-8"))
			     );
		X509Certificate mCertificate = (X509Certificate) myCert;
		PublicKey publicKey = mCertificate.getPublicKey();
		System.out.println(publicKey.getEncoded());
		Boolean isValidCrl = XMLVerifier.verifyCRL(mCertificate);
		System.out.println(isValidCrl);
	}
	
	public static void test1(){
		String certString1 = "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";
		String certString2 = "MIIF7zCCBNegAwIBAgIRANdVj9r18RBbshMoK3B3KaMwDQYJKoZIhvcNAQEFBQAwgZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR8wHQYDVQQDExZVVE4tVVNFUkZpcnN0LUhhcmR3YXJlMB4XDTExMDMxNTAwMDAwMFoXDTE0MDMxNDIzNTk1OVowgd8xCzAJBgNVBAYTAlVTMQ4wDAYDVQQREwUzODQ3NzEQMA4GA1UECBMHRmxvcmlkYTEQMA4GA1UEBxMHRW5nbGlzaDEXMBUGA1UECRMOU2VhIFZpbGxhZ2UgMTAxFDASBgNVBAoTC0dvb2dsZSBMdGQuMRMwEQYDVQQLEwpUZWNoIERlcHQuMSgwJgYDVQQLEx9Ib3N0";
		//before decoding we need to get rod off the prefix and suffix
	    byte [] decoded = Base64.decode(certString1.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", ""));
	    //byte[] decoded = Base64.decode(certString1);
		try {
			X509Certificate mCertificate = (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(decoded));
			PublicKey publicKey = mCertificate.getPublicKey();
			System.out.println(bytesToHex(publicKey.getEncoded()));
			//Boolean isValidCrl = XMLVerifier.verifyCRL(mCertificate);
			//System.out.println(isValidCrl);
		} catch (CertificateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	public static int validateCustomer(AccountCA accountCa){
		//check customer exist
		if((accountCa == null) || (accountCa.getCustomerId() == null)){
			return ErrorCodes.VERIFY_CUSTOMER.CUSTOMER_NOT_EXIST;
		}
		
		//check account-ca status
		if(accountCa.getAccountCaStatus() != ErrorCodes.ACCOUNT_CA_STATUS.ACTIVE){
			return ErrorCodes.VERIFY_CUSTOMER.ACCOUNT_CA_INACTIVE;
		}
		
		//check is Nacencomm
		if(!isNacencommCa(accountCa.getAccountCaIssuer())){
			return ErrorCodes.VERIFY_CUSTOMER.CA_NOT_SUPPORT;
		}
		
		//check partner exist
		if(TblAccountCADAO.getPartnerStatus(accountCa.getPartnerId()) == ErrorCodes.PARTNER_STATUS.PARTNER_NOT_FOUND){
			return ErrorCodes.VERIFY_CUSTOMER.PARTNER_NOT_FOUND;
		}
		
		//check partner status
		if(TblAccountCADAO.getPartnerStatus(accountCa.getPartnerId()) != ErrorCodes.PARTNER_STATUS.ACTIVE){
			return ErrorCodes.VERIFY_CUSTOMER.PARTNER_NOT_ACTIVE;
		}
		
		return ErrorCodes.VERIFY_CUSTOMER.VALID_CUSTOMER;
	}
	
	
	public static EncryptStringResult encryptString(String encodedBase64String, String customerId) {
		EncryptStringResult encryptStringResult = new EncryptStringResult();
		try{
			AccountCA accountCa = TblAccountCADAO.getAccountCA(customerId);
			int isValidCustomer = validateCustomer(accountCa);
			System.out.println(isValidCustomer);
			if(isValidCustomer != ErrorCodes.VERIFY_CUSTOMER.VALID_CUSTOMER){
				encryptStringResult.setErrorCode(isValidCustomer);
				return encryptStringResult;
			}
			
			String pubKey = requiredInfo + accountCa.getPublicKey();
			PublicKey publicKey = getPublicKey(pubKey);
			String encrytedText = encryptData(encodedBase64String, publicKey);
			encryptStringResult.setEncryptedResult(encrytedText);
			encryptStringResult.setErrorCode(0);
			return encryptStringResult;
		}catch (Exception e) {
			e.printStackTrace();
			encryptStringResult.setErrorCode(-2);
			return encryptStringResult;
		}
		
	}
	
	
	public static SignStringResult signString(String base64String) {
		    SignStringResult signStringResult = new SignStringResult();
		    try{
		    	PrivateKey privateKey = getPrivateKey();
		    	byte[] data = Base64Utils.base64Decode(base64String);
		    	Signature sig = Signature.getInstance("SHA1withRSA");
		    	sig.initSign(privateKey);
		    	sig.update(data);
		    	byte[] signatureBytes = sig.sign();
		    	String signedText = Base64Utils.base64Encode(signatureBytes);
		    	
		    	signStringResult.setErrorCode(0);
		    	signStringResult.setErrorMessage("Sign successfully!");
		    	signStringResult.setSignedString(signedText);
		    }catch(Exception e){
		    	e.printStackTrace();
		    	signStringResult.setErrorCode(-2);
		    	signStringResult.setErrorMessage("Exception: " + e.getMessage());
		    }
		return signStringResult;	
	}
	
	
	/** 
     * Encrypt Data 
     * @param data 
     * @throws IOException 
     */  
    private static String encryptData(String encodedBase64String, PublicKey publicKey) throws IOException {  
        byte[] dataToEncrypt = Base64Utils.base64Decode(encodedBase64String);  
        byte[] encryptedData = null;  
        try {  
            Cipher cipher = Cipher.getInstance("RSA");  
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
            encryptedData = cipher.doFinal(dataToEncrypt);  
            System.out.println("Encryted Data: " + encryptedData);  
              
        } catch (Exception e) {  
            e.printStackTrace();  
        }     
          
        return Base64Utils.base64Encode(encryptedData);
    }  
  
    /** 
     * Encrypt Data 
     * @param data 
     * @throws IOException 
     */  
    private static String decryptData(String encodedBase64String, PrivateKey privateKey) throws IOException {  
        byte[] descryptedData = null;  
          
        try {  
            Cipher cipher = Cipher.getInstance("RSA");  
            cipher.init(Cipher.DECRYPT_MODE, privateKey);  
            descryptedData = cipher.doFinal(Base64Utils.base64Decode(encodedBase64String));  
              
        } catch (Exception e) {  
            e.printStackTrace();  
        }     
          
        return Base64Utils.base64Encode(descryptedData);
    }  
	
    
	public static PrivateKey getPrivateKey() throws KeyStoreException, NoSuchProviderException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException {
		loadProperties();
		KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI" );
        keyStore.load(null, null);
        Enumeration enumeration = keyStore.aliases();
        while (enumeration.hasMoreElements()) {
            String alias = enumeration.nextElement().toString();
            //System.out.println("" + alias);
            keyStore.getCertificateChain(alias);
            KeyPair keyPair = getPrivateKey(keyStore, alias, certPassword.toCharArray());
            if (keyPair != null) {
                return keyPair.getPrivate();
            }            
        }
        return null;
    }
	
	public static void loadProperties(){
		String fileName = RootConfig.shareInstance().getRoot() + "config/database.conf";	
		try {
			props.load(new FileInputStream(fileName));
		} catch (Exception e) {
			e.printStackTrace();
			certPassword = "12345";
		}  
		certPassword = props.getProperty("certPassword", certPassword);
	}

	public static KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password) {
        try {
            Key key = keystore.getKey(alias, password);
            if (key instanceof PrivateKey) {
                Certificate cert = keystore.getCertificate(alias);
                PublicKey publicKey = cert.getPublicKey();
                return new KeyPair(publicKey, (PrivateKey) key);
            }
        }catch(Exception e){
        	System.out.println("[Exception]" + e.getMessage());
        }
        return null;
    }
}
